package com.rgs.base.database.mapper;

import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;


public class BaseSelectExtendProvider extends MapperTemplate {
    public BaseSelectExtendProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    public String selectSumGroupBy(MappedStatement ms) {
        return commonSelectSumGroupBy(ms, false);
    }

    public String commonSelectSumGroupBy(MappedStatement ms, boolean withForceIndex) {
        Class<?> entityClass = getEntityClass(ms);

        setResultType(ms, entityClass);

        StringBuilder sql = new StringBuilder("SELECT\n");
        if (isCheckExampleEntityClass()) {
            sql.append(SqlHelper.exampleCheck(entityClass));
        }
//        sql.append("<if test=\"distinct\">distinct</if>");
        sql.append(this.sumSelectColumns());
        //设置max的sql，且不做groupby
        sql.append(this.sumMaxColumns());

        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));

        if (withForceIndex) {
            // 设置force index
            sql.append(this.setForceIndex());
        }

//        sql.append(SqlHelper.exampleWhereClause());
        sql.append(SqlHelper.updateByExampleWhereClause());
        sql.append(this.groupByColumns());
//        sql.append(SqlHelper.exampleOrderBy(entityClass));
        return sql.toString();
    }

    public String selectSumGroupByWithForceIndex(MappedStatement ms) {
        return commonSelectSumGroupBy(ms, true);
    }

    private String setForceIndex() {
        StringBuilder sql = new StringBuilder(" ");
        sql.append("<if test=\"forceIndexList !=null and forceIndexList.size>0\">\n");
        sql.append("FORCE INDEX \n");
        sql.append("<foreach collection=\"forceIndexList\" item=\"item\" open=\"(\" close=\")\" separator=\",\">\n");
        sql.append("${item}");
        sql.append("</foreach>\n");
        sql.append("</if>\n");
        return sql.toString();
    }


    public String selectSumGroupByFull(MappedStatement ms) {
        return customSelectSumGroupBy(ms, false);
    }

    public String customSelectSumGroupBy(MappedStatement ms, boolean needCount) {
        Class<?> entityClass = getEntityClass(ms);
        setResultType(ms, entityClass);

        StringBuilder sql = new StringBuilder("SELECT\n");
        if (isCheckExampleEntityClass()) {
            sql.append(SqlHelper.exampleCheck(entityClass));
        }
        sql.append(this.sumSelectColumns());
        if (needCount) {
            // 拼接count(1) AS xxx
            sql.append(this.countColumn());
        }
        //设置max的sql，且不做groupBy
        sql.append(this.sumMaxColumns());

        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));

        sql.append(SqlHelper.updateByExampleWhereClause());
        // 自定义sql
        sql.append(this.getCustomSql());
        sql.append(this.groupByColumns());
        // orderBy字段
        sql.append(this.getOrderByColumns());
        return sql.toString();
    }

    private String countColumn() {
        StringBuilder sql = new StringBuilder();
        sql.append("<if test=\"countAlias !=null \">\n");
        sql.append(",");
        sql.append("count(1) AS ${countAlias}");
        sql.append("</if>\n");
        return sql.toString();
    }

    public String selectSumGroupByFullWithCount(MappedStatement ms) {
        return customSelectSumGroupBy(ms, true);
    }


    private String sumSelectColumns() {
        StringBuilder sql = new StringBuilder();
//        sql.append("<choose>");
        //sum条件
        sql.append("<if test=\"sumColumnList !=null and sumColumnList.size>0\">\n");
        sql.append("<foreach collection=\"sumColumnList\" item=\"item\" separator=\",\">\n");
        sql.append("IFNULL(sum(${item}),0) as ${item}");
        sql.append("</foreach>\n");

        //,判断
        sql.append("<if test=\"groupByList !=null and groupByList.size>0\">");
        sql.append(",");
        sql.append("</if>");
        sql.append("</if>\n");

        //group条件
        sql.append("<if test=\"groupByList !=null and groupByList.size>0\">\n");
        sql.append("<foreach collection=\"groupByList\" item=\"item\" separator=\",\">\n");
        sql.append("${item}");
        sql.append("</foreach>\n");
        sql.append("</if>\n");
        //不支持指定列的时候查询全部列
//        sql.append("<otherwise>");
//        sql.append(getAllColumns(entityClass));
//        sql.append("</otherwise>");
//        sql.append("</choose>");
//        orderByColumns(sql);
        return sql.toString();
    }

    private String sumMaxColumns() {
        StringBuilder sql = new StringBuilder();
        sql.append("<if test=\"maxColumnList !=null and maxColumnList.size>0\">\n");
        sql.append(",");
        sql.append("<foreach collection=\"maxColumnList\" item=\"item\" separator=\",\">\n");
        sql.append("max(${item}) as ${item}");
        sql.append("</foreach>\n");
        sql.append("</if>\n");
        return sql.toString();
    }

    private String groupByColumns() {
        StringBuilder sql = new StringBuilder(" ");
        sql.append("<if test=\"groupByList !=null and groupByList.size>0\">\n");
        sql.append("GROUP BY \n");
        sql.append("<foreach collection=\"groupByList\" item=\"item\" separator=\",\">\n");
        sql.append("${item}");
        sql.append("</foreach>\n");
        sql.append("</if>\n");
        return sql.toString();
    }

    private String getOrderByColumns() {
        return " " + "<if test=\"orderByList !=null and orderByList.size>0\">\n" +
                "ORDER BY \n" +
                "<foreach collection=\"orderByList\" item=\"item\" separator=\",\">\n" +
                "${item}" +
                "</foreach>\n" +
                "</if>\n";
    }

    private String getCustomSql() {
        return " " + "<if test=\"customSql !=null and customSql.size>0\">\n" +
                "AND \n" +
                "<foreach collection=\"customSql\" item=\"item\" separator=\",AND\">\n" +
                "${item}" +
                "</foreach>\n" +
                "</if>\n";
    }

//    private void orderByColumns(StringBuilder sql){
//        sql.append("<if test=\" orderByStr != null and orderByStr.length>0 \">");
//        sql.append("order by ${orderByStr}");
//        sql.append("</if>");
//    }
}
